package pl.oczadly.jabberclient.mainwindow.view;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.Vector;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Mode;
import org.jivesoftware.smack.packet.Presence.Type;

import pl.oczadly.jabberclient.connection.ConnectionHolder;
import pl.oczadly.jabberclient.mainwindow.model.Account;
import pl.oczadly.jabberclient.mainwindow.model.MyListModel;
import pl.oczadly.jabberclient.message.view.MessageView;
import pl.oczadly.jabberclient.message.view.manager.MessageViewManager;
import pl.oczadly.jabberclient.utils.Fonts;
import pl.oczadly.jabberclient.utils.NameValidator;
import pl.oczadly.jabberclient.utils.Utils;

public class MainView implements IMainView {

	private JFrame frame;
	private JComboBox statusCombo;
	
	private MyListModel myModel = MyListModel.getInstance();
	private Vector<Account> model = myModel.getAll();
	private JList contactList;

	public void createUI() {
		frame = new JFrame( Utils.WINDOW_TITLE );

		addGridBagLayout( frame );
		addMenu( frame );
		addContactList();
		
		ChatManager chatManager = ConnectionHolder.getConnection().getChatManager();
		chatManager.addChatListener( new MyChatManagerListener() );
		
		frame.setSize( 300, 400 );
		frame.setVisible( true );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
	}
	
	public void close() {
		frame.dispose();
		System.exit( 0 );
	}
	
	public void setStatus() {
		String status = JOptionPane.showInputDialog( frame, Utils.STATUS_PRESENCE, Utils.STATUS_WINDOW_TITLE, 1 );
		Utils.setStatus( status );
	}
	
	private void addMenu( JFrame frame ) {
		JMenuBar menuBar = new JMenuBar();
		
		GeneralView generalView = new GeneralView( this );
		generalView.addGeneralView( menuBar );
		
		ContactsView contactsView = new ContactsView( contactList );
		contactsView.addContactsView( menuBar );
		
		HelpView helpView = new HelpView();
		helpView.addHelpView( menuBar );
		
		frame.setJMenuBar( menuBar );
	}
	
	
	private void addContactList() {
		Roster roster = ConnectionHolder.getConnection().getRoster();
		Collection<RosterEntry> entries = roster.getEntries();
		
		for( RosterEntry rosterEntry : entries ) {
			String user = rosterEntry.getUser();
			String name = rosterEntry.getName();
			
			myModel.add( user, name );
			contactList.setListData( myModel.getAll() );
		}
	}
	private void addGridBagLayout( JFrame frame ) {
		GridBagLayout layout = new GridBagLayout();
		frame.getContentPane().setLayout( layout );
		
		JLabel helloLabel = new JLabel( Utils.HELLO + Utils.getLogin() );
		helloLabel.setFont( Fonts.ACCOUNT_FONT );
		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.FIRST_LINE_START;
		c.gridx = 0;
		c.gridy = 0;
		c.insets = new Insets( 1, 5, 1, 0 );
		frame.add( helloLabel, c );
		
		statusCombo = new JComboBox( Utils.PRESENCES );
		statusCombo.addActionListener( new StatusListener() );
		c.anchor = GridBagConstraints.LINE_START;
		c.gridx = 0;
		c.gridy = 1;
		frame.add( statusCombo, c );
		
		contactList = new JList( model );
		contactList.addKeyListener( new MyKeyListener() );
		contactList.addMouseListener( new MyMouseListener() );
		
		JScrollPane scroller = new JScrollPane( contactList );
		scroller.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED );
		scroller.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
		c.gridy = 0;
		c.gridy = 2;
		c.weightx = 1.0;
		c.weighty = 1.0;
		c.gridwidth = frame.getWidth();
		c.gridheight = frame.getHeight();
		c.fill = GridBagConstraints.BOTH;
		
		frame.add( scroller, c );
	}
	
	private void openMessageWindow() {
		Account ac = (Account) contactList.getSelectedValue();
		
		Roster roster = ConnectionHolder.getRoster();
		System.out.println( ac.getId() );
		roster.getEntry( ac.getId() );
		
		MessageView msgView = new MessageView( ac.getId(), ac.getName() );
		msgView.createUI();
		
	}

	private class StatusListener implements ActionListener {
		public void actionPerformed( ActionEvent e ) {
			JComboBox cb = (JComboBox)e.getSource();
	        String cbPresense = (String)cb.getSelectedItem();
	        Presence presence = null;
	        
	        if( cbPresense.equals( Utils.AVAILABLE_PRESENCE ) )
				presence = new Presence( Type.available );

	        if( cbPresense.equals( Utils.UNAVAILABLE_PRESENCE ) )
	        	presence = new Presence( Type.unavailable );
	        	
			if( cbPresense.equals( Utils.STATUS_PRESENCE ) ) {
	        	MainView.this.setStatus();
	        	presence = new Presence( Presence.Type.available, Utils.getStatus(), 10, Mode.available );
	        }
	        
	        ConnectionHolder.getConnection().sendPacket( presence );
		}
	}

	private class MyKeyListener implements KeyListener {

		public void keyTyped( KeyEvent e ) {}

		public void keyPressed( KeyEvent e ) {
			if( e.getKeyCode() == KeyEvent.VK_ENTER ) {
				openMessageWindow();
			}
		}

		public void keyReleased( KeyEvent e ) {}
		
	}
	
	private class MyMouseListener extends MouseAdapter {

	public void mouseClicked( MouseEvent e ){
		if( e.getClickCount() == 2 ) {
			openMessageWindow();
		}
	}
		
	}

	private class MyChatManagerListener implements ChatManagerListener {

		public void chatCreated( Chat chat, boolean arg1 ) {
			chat.addMessageListener( new MyMessageListener() );
		}
		
	}
	
	private class MyMessageListener implements MessageListener {

		public void processMessage( Chat chat, Message message ) {
			if( !MessageViewManager.contains( NameValidator.parse( message.getFrom() ) ) ) {
				MessageView msgView = new MessageView( message.getFrom(), message.getFrom() );
				msgView.createUI();
				msgView.setMessage( message.getFrom(), message.getBody() );
			}
			
		}
		
	}
}
